﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
using DevExpress.Xpo.DB;
using DevExpress.Xpo;
using System.Reflection;
using DevExpress.XtraTreeList;
using DevExpress.XtraTreeList.Nodes;
using SqlData;

namespace 干涉检查Demo
{
    public partial class FrmInterface : DevExpress.XtraEditors.XtraForm
    {
        private SldWorks swApp = null;
        ModelDoc2 swModeldoc;
        AssemblyDoc swAsm;
        InterferenceDetectionMgr pIntMgr = default(InterferenceDetectionMgr);
        DataTable dt = null;
        DataRow dr = null;

        public FrmInterface()
        {
            InitializeComponent();

            bool hasGet = GetSW();
            if (hasGet == false)
            {
                MessageBox.Show("关联SW失败");
                return;
            }

            checkEdit9.Checked = true;//默认透明 

            dt = new DataTable();
            dt.Columns.Add("Name");
            dt.Columns.Add("FileA");
            dt.Columns.Add("FileB");
            dt.Columns.Add("Volume");
            dt.Columns.Add("Remark");
            dt.Columns.Add("Interference",typeof(bool));


            treeList1.OptionsBehavior.ReadOnly = true;
            treeList1.OptionsBehavior.Editable = false;
            treeList1.OptionsView.AllowHtmlDrawHeaders = true;
            treeList1.OptionsView.ColumnHeaderAutoHeight = DevExpress.Utils.DefaultBoolean.False;
            treeList1.OptionsView.FocusRectStyle = DevExpress.XtraTreeList.DrawFocusRectStyle.RowFullFocus;
            treeList1.ViewStyle = TreeListViewStyle.TreeList;
            treeList1.Appearance.FocusedCell.BackColor = Color.Lavender;//颜色
            treeList1.OptionsSelection.EnableAppearanceFocusedCell = false;
        }

        /// <summary>
        /// 关联进程
        /// </summary>
        /// <returns></returns>
        private bool GetSW()
        {
            if (swApp == null)
            {
                try
                {
                    object marSW = System.Runtime.InteropServices.Marshal.GetActiveObject("SldWorks.Application");//关联当前打开的Solidworks 
                    if (marSW == null)
                    {
                        MessageBox.Show("关联SolidWorks失败");
                        return false;
                    }
                    swApp = (SldWorks)marSW;
                    return true;
                }
                catch (Exception)
                {

                    return false;
                }

            }
            return true;
        }


        //开始检查
        private void SimpleButton1_Click(object sender, EventArgs e)
        {
            treeList1.Nodes.Clear();

            try
            {
                swModeldoc = swApp.ActiveDoc;
                if (swModeldoc == null)
                {
                    MessageBox.Show("尚未打开任何文件");
                    return;
                };
                textEdit1.Text = swModeldoc.GetTitle();

                if (swModeldoc != null && swModeldoc.GetType() != (int)swDocumentTypes_e.swDocASSEMBLY)  // 检查是否为装配体
                {
                    MessageBox.Show("当前打开的不是装配体");
                    return;
                }
                 
                swAsm = (AssemblyDoc)swModeldoc;
                object[] vInts = null;
                long i = 0;
                long j = 0;
                IInterference interference = default(IInterference); 
                object vIntComps = null;
                object[] vComps = null;
            
                double vol = 0;
                object vTrans = null;
                bool ret = false;


                //  swAsm.ToolsCheckInterference();//调用干扰检测窗体
                pIntMgr = swAsm.InterferenceDetectionManager;
                  
                //指定干扰检测设置及选项
                //pIntMgr.TreatCoincidenceAsInterference = false;//将重合实体视为干涉
                //pIntMgr.TreatSubAssembliesAsComponents = false; //将子装配体视为单个零部件，以便不报告子装配体零部件之间的干涉。
                //pIntMgr.IncludeMultibodyPartInterferences = true;//多实体零件中实体之间的干涉
                //pIntMgr.MakeInterferingPartsTransparent = true;//透明模式下显示选定干涉的零部件
                //pIntMgr.CreateFastenersFolder = false;//创建紧固件文件夹
                //pIntMgr.IgnoreHiddenBodies = false;//忽略隐藏的实体
                //pIntMgr.ShowIgnoredInterferences = false;//显示忽略的干涉
                //pIntMgr.UseTransform = false;//是否在干扰检测中使用转换 
                pIntMgr.TreatCoincidenceAsInterference = checkEdit1.Checked;//将重合实体视为干涉
                pIntMgr.TreatSubAssembliesAsComponents = checkEdit3.Checked; //将子装配体视为单个零部件，以便不报告子装配体零部件之间的干涉。
                pIntMgr.IncludeMultibodyPartInterferences = checkEdit4.Checked;//包括多实体零件中干涉
                pIntMgr.MakeInterferingPartsTransparent = checkEdit5.Checked;//透明模式下显示选定干涉的零部件
                pIntMgr.CreateFastenersFolder = false;//创建紧固件文件夹
                pIntMgr.IgnoreHiddenBodies = checkEdit6.Checked;//忽略隐藏的实体
                pIntMgr.ShowIgnoredInterferences = checkEdit2.Checked;//显示忽略的干涉
                pIntMgr.UseTransform = false;//是否在干扰检测中使用转换
                 
                vInts = (object[])pIntMgr.GetInterferences();   //运行干扰检测
                                                                //MessageBox.Show("Number of interferences: " + pIntMgr.GetInterferenceCount()); 
                ret = pIntMgr.GetComponentsAndTransforms(out vIntComps, out vTrans);  //获取干扰组件和变换 
                int t = 0;

                if (vInts.Count()>0)//数量大于0
                {
                    string conStr = "";
                    XpoCon.store = XpoDefault.GetConnectionProvider(conStr, AutoCreateOption.None);   //建立数据库连接;  
                    XpoCon.UnitOfShort.TrackPropertiesModifications = true;
                    XpoCon.UnitOfLong.TrackPropertiesModifications = true;
                    SessionData(conStr ,nameof(SqlData));
                }

                //获取干扰信息
                for (i = 0; i <= vInts.GetUpperBound(0); i++)
                {
                    interference = (IInterference)vInts[i];
                    // MessageBox.Show("Number of components in this interference:" + interference.GetComponentCount());
                    vComps = (object[])interference.Components;
                    t++;

                    dr = dt.NewRow();
                    dr["Name"] = "干涉" + t;
                    for (j = 0; j <= vComps.GetUpperBound(0); j++)
                    {
                        Component2 comp = (Component2)vComps[j];
                        string config = comp.ReferencedConfiguration;//活动配置
                        string state = comp.ReferencedDisplayState;//参考的显示状态 
                        var materil = comp.MaterialPropertyValues;

                        comp.GetConstrainedStatus();//获取抑制状态，确认是否压缩、轻化、还原
                        comp.GetSuppression2();//草图约束状态  
                        if (comp.IsSuppressed())//如果被抑制则设定位还原
                        {
                            comp.SetSuppression2((int)swComponentSuppressionState_e.swComponentFullyResolved);//设置还原
                        }

                        string fileName = null;
                        ModelDoc2 compModel = comp.GetModelDoc2(); // 获取组件对应的模型文档
                        if (j == 0)
                        {
                            dr["FileA"] = compModel.GetTitle();
                            fileName = compModel.GetTitle();
                        }
                        else if (j == 1)
                        {
                            dr["FileB"] = compModel.GetTitle();
                            fileName = compModel.GetTitle();
                        }

                        vol = interference.Volume;
                        dr["Volume"] = (vol * 1000000000).ToString("F2") + " mm^3";
                         

                        bool hasAbsolute = false; 
                        hasAbsolute = AbsoluteCalculation.GetAbsoluteCalculation(fileName);//绝对计算检查
                        if (hasAbsolute == true)
                        {
                            dr["Remark"] = "绝对计算: "+ fileName;
                            dr["Interference"] = true ;
                            continue;
                        }
                        else
                        { 
                            hasAbsolute = SingleNotCalculated.GetSingleNotCalculated(fileName);//单个绝对不计算
                            if (hasAbsolute==true)
                            {
                                dr["Remark"] = "绝对不计算: "+ fileName;
                                dr["Interference"] = false  ;
                                continue;
                            }
                            else
                            {
                                //hasAbsolute = GroupsNotCalculated.GetGroupsNotCalculated(fileName);//组绝对不计算
                                //if (hasAbsolute==true)
                                //{
                                //    dr["Remark"] = "绝对不计算: " + fileName;
                                //    dr["Interference"] = false;
                                //    continue;
                                //}
                                //else
                                //{

                                //}

                            }

                            dr["Interference"] = true;
                        }

             
                       // comp.SetSuppression2((int)swComponentSuppressionState_e.swComponentFullyLightweight);//设置轻化
                    }
                    dt.Rows.Add(dr); 
                }

                treeList1.DataSource = dt;
            }
            catch (Exception ex)
            {
                pIntMgr.Done();//结束
                MessageBox.Show(ex.Message);
            }

        }

        /// <summary>
        /// 异步更新数数据库结构
        /// </summary>
        /// <returns></returns>
        public static bool SessionData(string srString, string typeName)
        {
            try
            {
                using (DevExpress.Xpo.Session session = new DevExpress.Xpo.Session())
                {
                    Assembly assembly = Assembly.GetExecutingAssembly();  // 获取当前程序集 
                    Type[] types = assembly.GetTypes(); // 获取程序集中的所有类型  
                    var typesInNamespace = types     // 过滤并列出指定命名空间中的所有类型
                        .Where(t => t.Namespace == typeName && t.FullName == typeName + "." + t.Name).ToList();//重点在FullName，命名空间+类型名称  
                    session.ConnectionString = srString;//连接到数据库
                    session.Connect();

                    foreach (var type in typesInNamespace)
                    {
                        session.UpdateSchema(type);//循环添加数据
                    }
                    return true;
                }
            }
            catch (Exception ex)
            {

                Msg.ErrorMessageShow(ex.Message);
                return false;
            }
        }

        //结束检查
        private void simpleButton2_Click(object sender, EventArgs e)
        {
            if (pIntMgr != null)
            {
                pIntMgr.Done();
                treeList1.Nodes.Clear();
            }

        }

        //导出
        private void SimpleButton3_Click(object sender, EventArgs e)
        {
            if (pIntMgr != null)
            {
                pIntMgr.ExportResults(@"C:\Users\Administrator\Desktop\IntDetReport.xlsx", true);
            }
        }



        //透明
        private void CheckEdit9_CheckedChanged(object sender, EventArgs e)
        {
            if (pIntMgr != null)
            {
                pIntMgr.NonInterferingComponentDisplay = (int)swNonInterferingComponentDisplay_e.swNonInterferingComponentDisplay_Transparent;
            }

            checkEdit7.Checked = false;
            checkEdit8.Checked = false;
            checkEdit10.Checked = false;
        }

        //线架
        private void CheckEdit7_CheckedChanged(object sender, EventArgs e)
        {
            if (pIntMgr != null)
            {
                pIntMgr.NonInterferingComponentDisplay = (int)swNonInterferingComponentDisplay_e.swNonInterferingComponentDisplay_Wireframe;
            }
            checkEdit8.Checked = false;
            checkEdit9.Checked = false;
            checkEdit10.Checked = false;
        }

        //隐藏
        private void CheckEdit8_CheckedChanged(object sender, EventArgs e)
        {
            if (pIntMgr != null)
            {
                pIntMgr.NonInterferingComponentDisplay = (int)swNonInterferingComponentDisplay_e.swNonInterferingComponentDisplay_Hidden;
            }
            checkEdit7.Checked = false;
            checkEdit9.Checked = false;
            checkEdit10.Checked = false;
        }
        //当前项
        private void CheckEdit10_CheckedChanged(object sender, EventArgs e)
        {
            if (pIntMgr != null)
            {
                pIntMgr.NonInterferingComponentDisplay = (int)swNonInterferingComponentDisplay_e.swNonInterferingComponentDisplay_Current;
            }

            checkEdit7.Checked = false;
            checkEdit8.Checked = false;
            checkEdit9.Checked = false;
        }

        private void TreeList1_MouseDown(object sender, MouseEventArgs e)
        {
            try
            {
                Point point = new Point(e.X, e.Y);
                TreeListHitInfo info = treeList1 .CalcHitInfo(point);
                if (info.InColumnPanel == false)//屏蔽行头
                {
                    if (e.Button == MouseButtons.Right)
                    {
                        TreeListNode treeNode = info.Node;
                        treeList1 .SetFocusedNode(treeNode);
                       // treeList1 (sender, e);
                        popupMenu1.ShowPopup(MousePosition);
                    }
                }
            }
            catch (Exception ex)
            { 
                Msg.ErrorMessageShow(ex.Message);
            }
        }

        //零件A绝对不计算
        private void BarButtonItem1_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (treeList1.AllNodesCount == 0) return;

            try
            {
                string fileA = treeList1.GetFocusedRowCellValue("FileA").ToString();
                bool hasFile = FileName.GetFileName(fileA);//检查文件名称是否存在
                SingleNotCalculated.SetSingleNotCalculated(fileA);
            }
            catch (Exception ex)
            {
                Msg.ErrorMessageShow(ex.Message);
            }

        }

        private void SimpleButton4_Click(object sender, EventArgs e)
        {
            try
            {
                swModeldoc = swApp.ActiveDoc;
                if (swModeldoc == null)
                {
                    MessageBox.Show("尚未打开任何文件");
                    return;
                };

                 
                //// 设置材料明细表相关的自定义属性（示例：设置数量属性） 
                ////customPropMgr.Add3("材料明细表数量", (int)swCustomInfoType_e.swCustomInfoText, "5", 0);
                //DesignTable xx = swModeldoc.GetDesignTable ();
                //Msg.ErrorMessageShow(xx.GetVisibleRowCount().ToString());
                //Msg.ErrorMessageShow(xx.Worksheet);
                 
                Configuration swConfig = default(Configuration);
                Configuration swParentConfig = default(Configuration);
                ConfigurationManager swConfMgr = default(ConfigurationManager);
                object[] vChildConfigArr = null;
                Configuration swChildConfig = default(Configuration);

            
                 
                object[] vConfigNameArr = (string[])swModeldoc.GetConfigurationNames();
                foreach (string vConfigName in vConfigNameArr)
                {
                    swConfig = (Configuration)swModeldoc.GetConfigurationByName(vConfigName);
                    Msg.ErrorMessageShow("    Description = " + swConfig.Description);
                    Msg.ErrorMessageShow("  Configuration name = " + swConfig.Name);
                    swConfig.UseDescriptionInBOM = false;
                    swConfig.UseAlternateNameInBOM = false;
                 
                    Msg.ErrorMessageShow("    Display description in bill of materials? " + swConfig.UseDescriptionInBOM);
                    // Process parent
                    swParentConfig = (Configuration)swConfig.GetParent();
                    if ((swParentConfig != null))
                    {
                        Msg.ErrorMessageShow("      Parent = " + swParentConfig.Name);
                    }
                    // Process children
                    vChildConfigArr = (object[])swConfig.GetChildren();
                    if ((vChildConfigArr != null))
                    {
                        foreach (object vChildConfig in vChildConfigArr)
                        {
                            swChildConfig = (Configuration)vChildConfig;
                            Msg.ErrorMessageShow("      Child = " + swChildConfig.Name);
                        }
                    }

                }

            }
            catch (Exception)
            {

                throw;
            }

        }
    }
}
 